home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 34.zip / BS1 part 34 / FredFish PD 319.adf / CNewsSrc / uupc.lzh / uupc / dcpxfer.c < prev    next >
C/C++ Source or Header  |  1990-01-16  |  10KB  |  447 lines

  1. /*
  2.  *    dcpxfer.c
  3.  *
  4.  *    Revised edition of DCP
  5.  *
  6.  *    Stuart Lynne May/87
  7.  *    Copyright (c) Richard H. Lamb 1985, 1986, 1987
  8.  *    Changes Copyright (c) Stuart Lynne 1987
  9.  *
  10.  *    $Id: dcpxfer.c,v 1.2 90/01/16 10:25:25 crash Exp Locker: crash $
  11.  */
  12.  
  13. #ifndef lint
  14. static char RCSid[] = "$Id: dcpxfer.c,v 1.2 90/01/16 10:25:25 crash Exp Locker: crash $";
  15. #endif /* lint */
  16.  
  17. /*
  18.  *    "DCP" is a uucp clone.  Copyright Richard H. Lamb 1985, 1986, 1987
  19.  *
  20.  *    file send/receive routines
  21.  */
  22.  
  23. #include "dcp.h"
  24.  
  25. #ifndef _U
  26. # include <ctype.h>
  27. #endif
  28.  
  29. #ifdef AMIGA
  30. void *IntuitionBase = 0, *OpenLibrary();
  31. void CloseLibrary();
  32. static unsigned long fileSecs, fileMicro;    /* For xmit logging purposes */
  33. #endif /* AMIGA */
  34.  
  35. int filecount;
  36. static long filetime, filesize;
  37. static char file_buf[256];            /* buffer used by rfile() & sfile() */
  38. static char *file_flds[10];            /* (ditto) */
  39.  
  40. static unsigned char    rpacket[MAXPACK];
  41. static unsigned char    spacket[MAXPACK];
  42.  
  43.  
  44. int closelibs(x)
  45. int x;
  46. {
  47.     if (IntuitionBase)    CloseLibrary(IntuitionBase), IntuitionBase = 0;
  48.     return( x );
  49. }
  50.  
  51.  
  52. void logtime(dir)
  53. char *dir;
  54. {
  55.     register struct tm *tim;    /* Start time in fields for display */
  56. #ifdef AMIGA
  57.     unsigned long Secs, Micro;    /* Current time (for calculating duration) */
  58.     register unsigned long thousandths;
  59.     register int msd;
  60. #else
  61.     long Secs, Micro;            /* Current time (for calculating duration) */
  62.     register unsigned long thousandths;
  63.     register int msd;
  64. #endif /* AMIGA */
  65.  
  66.     tim = localtime( &filetime );
  67.  
  68. #ifdef AMIGA
  69.     if (!IntuitionBase)
  70.         IntuitionBase = OpenLibrary("intuition.library", 0L);
  71.     if (IntuitionBase) {
  72.         CurrentTime( &Secs, &Micro );
  73.         if (Micro < fileMicro)
  74.             Secs -= fileSecs+1, Micro += 1000000L - fileMicro;
  75.         else
  76.             Secs -= fileSecs,   Micro -= fileMicro;
  77.         Micro /= 100000L;
  78.         thousandths = (100 * filesize) / (10 * Secs + Micro);
  79.     } else {
  80.         Secs = time( 0L ) - filetime;
  81.         Micro = 0;
  82.         thousandths = (10 * filesize) / Secs;
  83.     }
  84. #else /* !AMIGA */
  85.     Secs = time( 0L ) - filetime;
  86.     Micro = 0;
  87.     thousandths = (10 * filesize) / Secs;
  88. #endif /* AMIGA */
  89.  
  90.     msd = (int) (thousandths / 10L);
  91.     fprintf(syslog,                    /* 68 characters (usually) */
  92. "%s!%-6s %c (%02d/%02d-%02d:%02d:%02d) (C,PID,%02d) [SER:] %s %6ld bytes / %4ld.%01d secs, %3d.%01d baud\n",
  93.         rmtname, file_flds[3], remote == MASTER ? 'M' : 'S',
  94.         (int) tim->tm_mon+1, (int) tim->tm_mday,
  95.         (int) tim->tm_hour, (int) tim->tm_min, (int) tim->tm_sec,
  96.         ++filecount,
  97.         dir,
  98.         filesize, Secs, (int) Micro,        /* Faster than modulus?? */
  99.         msd, (int) (thousandths - msd * 10L)
  100.         );
  101.     closelibs(0);
  102. }
  103.  
  104.  
  105. /***************SEND PROTOCOL***************************/
  106. /*
  107.  *  sdata
  108.  *        send file data
  109.  */
  110. sdata()
  111. {
  112.     while( TRUE ) {
  113.         filesize += (long) size;
  114.         if ((*sendpkt) ( spacket, size, 0 ))
  115.             return (0 );                        /* send data */
  116.         if (( size = bufill( spacket )) == 0 )  /* Get data from file */
  117.             return( 'Z' );                     /* If EOF set state to that */
  118.     }
  119.     return('D');                            /* Got data, stay in state D */
  120. }
  121.  
  122.  
  123. /*
  124.  *  bufill
  125.  *        Get a bufferful of data from the file that's being sent.
  126.  *        8-bit & repeat count prefixes are not handled.
  127.  */
  128. bufill(buffer)
  129. char *buffer;
  130. {
  131.     return( read(fp, buffer, pktsize) );    /* Handle partial buffer */
  132. }
  133.  
  134.  
  135. /*
  136.  *  sbreak
  137.  *      send hangup request
  138.  */
  139. sbreak()
  140. {
  141.     int    len, i;
  142.     strcpy(spacket, "H");
  143.     if ((*sendpkt)(spacket, 0, 1))
  144.         return(0);
  145.     if ((*getpkt)(spacket, &len))
  146.         return(0);
  147.     printmsg( 1, "\n********************************\nSwitch modes" );
  148.     if (spacket[1] == 'N')
  149.         return('G');
  150.     return('Y');
  151. }
  152.  
  153.  
  154. /*
  155.  *  seof
  156.  *        send end-of-file.
  157.  */
  158. seof()
  159. {
  160.     int    len;
  161.  
  162.     if ((*sendpkt)(spacket, 0, 0))
  163.         return(0);
  164.     if ((*getpkt)(spacket, &len))
  165.         return(0);                    /* receive CY or CN */
  166.     if (strncmp(spacket, "CY", 2) != SAME)
  167.         return(0);                    /* couldn't copy file */
  168.  
  169.     close(fp);
  170.     fp = (-1);
  171.      importpath( hostfile, fromfile );
  172.     unlink(hostfile);
  173.     logtime("->");
  174.     printmsg( 0, "Transfer of %s (%s) completed.", fromfile, hostfile );
  175.     return('F');                    /* go get the next file to send */
  176. }
  177.  
  178.  
  179. /*
  180.  *  sfile
  181.  *        send file header
  182.  */
  183. sfile()
  184. {
  185.     int    i, len;
  186.     char * cp;
  187.     if (fp == -1) {                    /* If not already open, */
  188.         printmsg( 3, "looking for next file..." );
  189.         if (getfile()) {            /* get next file from current work */
  190.             fclose( fw );
  191.             unlink( cfile );        /* close and delete completed workfile */
  192.             fw = (FILE *) NULL;
  193.             return('B');            /* end sending session */
  194.         }
  195.          importpath( hostfile, fromfile );
  196.  
  197.         printmsg( 3, "Opening %s (%s) for sending", fromfile, hostfile );
  198.         fp = open(hostfile, 0);        /* open the file to be sent */
  199.         if (fp == -1) {                /* If bad file pointer, give up */
  200.             printmsg( 0, "Cannot open file %s (%s)", fromfile, hostfile );
  201.             return('A');
  202.         }
  203.     } else
  204.         return('A');    /* If something's already open, we're in trouble */
  205.  
  206.     printmsg( 1, "Sending %s (%s)\n\t%s", fromfile, hostfile, tofile );
  207.     strcpy(spacket, tofile);
  208.     if ((*sendpkt)(spacket, 0, 1))
  209.         return(0);                /* S fromfile tofile user - tofile 0666 */
  210.     if ((*getpkt)(spacket, &len))
  211.         return(0);
  212.     if (spacket[1] != 'Y')
  213.         return('A');             /* If otherside says NO, quit */
  214.     filetime = time( (long *) 0 );
  215.     filesize = 0L;
  216. #ifdef AMIGA
  217.     if (!IntuitionBase)
  218.         IntuitionBase = OpenLibrary("intuition.library", 0L);
  219.     if (IntuitionBase)
  220.         CurrentTime( &fileSecs, &fileMicro );
  221. #endif /* AMIGA */
  222.  
  223.     file_flds[3] = mailbox;
  224.     size = bufill(spacket);
  225.     return('D');
  226. }
  227.  
  228.  
  229. /*
  230.  *  sinit
  231.  *        send init:  send this host's parameters and get other side's back.
  232.  */
  233. sinit()
  234. {
  235.     if ((*openpk)())
  236.         return('A');
  237.     return('B');
  238. }
  239.  
  240.  
  241. /*
  242.  *    getfile
  243.  *
  244.  *    getfile reads the next line from the presently open workfile
  245.  *    (cfile) and determines from this the next file to be sent
  246.  *    (file). If there are no more, TRUE is returned.
  247.  *
  248.  *    --    A fix for "R from to 0666" should be done here to receive files
  249.  *        in addition to sending them.  The appropriate "state letter",
  250.  *        i.e. "R", should be returned to the "master" or "slave" state
  251.  *        switching table in "dcp.c"
  252.  *
  253.  *        I did not implement this since the majority of uucp transactions
  254.  *        appear to be "S from to 0666" type. RHLamb 1/87
  255.  *
  256.  *    [FJE]
  257.  *        Except when attempting to download from an anonymous uucp site!!
  258.  */
  259. getfile()
  260. {
  261.     int    i;
  262.     char    line[132];
  263.     register char * cp;
  264.  
  265.     if ( fgets( line, BUFSIZ, fw ) == (char *)NULL )
  266.         return(TRUE);
  267.  
  268.     sscanf(&line[2], "%s ", fromfile);
  269.     for ( i = 0, cp = line; *cp!='\0'; i++, cp++ ) {
  270.         if ( strncmp( cp, "0666", 4 ) == 0)
  271.             break;
  272.     }
  273.     cp += 4;
  274.     *cp = '\0';
  275.     strcpy(tofile, line);
  276.      printmsg(3, "\tgetfile: fromfile=%s;\n\t\ttofile=%s.", fromfile, tofile);
  277.     return(FALSE);
  278. }
  279.  
  280.  
  281. /*********************** MISC SUB SUB PROTOCOL *************************/
  282. /*
  283.  *    schkdir
  284.  *        scan the dir
  285.  */
  286. schkdir()
  287. {
  288.     char c;
  289.  
  290.     c = scandir();
  291.     if (c == 'Q') return('Y');            /* No files available */
  292.     if (c == 'S') {
  293.         strcpy(rpacket, "HN");
  294.         if ((*sendpkt)(rpacket, 0, 1))
  295.             return(0);
  296.     }
  297.     return('B');
  298. }
  299.  
  300.  
  301. /*
  302.  *    endp
  303.  *        end protocol
  304.  */
  305. endp()
  306. {
  307.     strcpy(rpacket, "HY");
  308.     (*sendpkt)(rpacket, 0, 2);            /* don't wait for ACK */
  309.     (*closepk)();
  310.     return('P');
  311. }
  312.  
  313.  
  314. /*********************  RECEIVE PROTOCOL  ********************/
  315. /*
  316.  *  rdata
  317.  *        receive data
  318.  */
  319. rdata()
  320. {
  321.     int    len;
  322.  
  323.     if ((*getpkt)(rpacket, &len))
  324.         return(0);
  325.     if (len == 0) {
  326.         close(fp);
  327.         strcpy(rpacket, "CY");
  328.         if ((*sendpkt)(rpacket, 0, 1))
  329.             return(0);
  330.         logtime("<-");
  331.         printmsg( 2, "Transfer complete\n" );
  332.         return('F');
  333.     }
  334.     filesize += write(fp, rpacket, len);    /* Write the data to the file */
  335.     return('D');                            /* Remain in data state */
  336. }
  337.  
  338.  
  339. /*
  340.  *  rfile
  341.  *        receive file header
  342.  */
  343. rfile()
  344. {
  345.     int        numflds;
  346.     int        len, i;
  347.     char    tmpfilename[256];        /* Holds the converted file name */
  348.     char    *cp, *index();
  349.  
  350.     printmsg( 3, "rfile entered" );
  351.     cp = file_buf;
  352.     while ( TRUE ) {
  353.         if ((*getpkt)( rpacket, &len )) {
  354.             printmsg( 5, "end connection" );
  355.             return( 0 );
  356.         }
  357.         strncpy( cp, rpacket, len );
  358.         cp += len;
  359.         if ( *(cp - 1) == '\0' ) break;
  360.     }
  361.     if (( file_buf[0] & 0x7f ) == 'H' ) /* FJE: Hangup mean all done?! */
  362.         return( 'C' );
  363.  
  364.     /* Convert upper case to lower [FJE: Why?  Does it matter?] */
  365.     for (cp = file_buf; *cp != '\0';cp++)
  366.         if (isupper(*cp)) *cp = tolower(*cp);
  367.  
  368.     /*
  369.      * Fields:
  370.      *  0        1            2        3  4        5        6
  371.      *
  372.      *    x D.ckctpab0008 D.boake20008 uucp - D.ckctpab0008 0666
  373.      *
  374.      *  |        |            |        |  |        |        |
  375.      *  |        |            |       who |        |        |
  376.      * What   src file    dest file  que'd|        |      file
  377.      *  to   (his name)   (my name)   it  |       ???     modes
  378.      *  do                               ???           (rw-rw-rw-)
  379.      */
  380.  
  381.     numflds = getargs( file_buf, file_flds );
  382.     cp = file_flds[2];
  383.     /*
  384.      *    Check for the funky stuff in the destination filename...
  385.      *
  386.      *    ~                -> $PUBDIR
  387.      *    ~uucp            -> $PUBDIR
  388.      *
  389.      *    ~/pathname        -> $PUBDIR/pathname        "pathname" may be empty
  390.      *    ~uucp/pathname    -> $PUBDIR/pathname
  391.      */
  392.     if (strcmp( cp, "~" ) == SAME || strcmp( cp, "~uucp" ) == SAME ) {
  393.         sprintf( tmpfilename, "%s/", pubdir );
  394.     } else if (!strncmp( cp, "~/", 2 ) || !strncmp( cp, "~uucp/", 6 )) {
  395.         sprintf( tmpfilename, "%s%s", pubdir, index(cp, '/'));
  396.     } else {
  397.         strcpy( tmpfilename, cp );
  398.     }
  399.     /* check for dirname only */
  400.     cp = tmpfilename + strlen( tmpfilename ) - 1;
  401.     if ( *cp == '\n' )
  402.         *cp-- = '\0';
  403.  
  404.     if ( *cp == '/' ) {
  405.         cp = rindex( file_flds[1], '/' );
  406.         if ( cp == (char *) NULL )
  407.             cp = file_flds[1];
  408.         else
  409.             cp++;
  410.         strcat( tmpfilename, cp );
  411.     } else
  412.         cp = file_flds[1];
  413.  
  414.     /* let host munge filename as appropriate */
  415.     importpath( tofile, tmpfilename );
  416.  
  417.     if ((fp = CREAT(tofile, 0775, 'b')) == -1) {    /* open a new file */
  418.         printmsg( 0, "cannot create %s", tofile );    /* Give up if can't */
  419.         return('A');
  420.     }
  421.     printmsg( 1, "Receiving %s as %s", file_flds[1], tofile );
  422.     strcpy(rpacket, "SY");
  423.     if ((*sendpkt)(rpacket, 0, 1))
  424.         return(0);
  425.     filetime = time( (long *) 0 );
  426.     filesize = 0L;
  427. #ifdef AMIGA
  428.     if (!IntuitionBase)
  429.         IntuitionBase = OpenLibrary("intuition.library", 0L);
  430.     if (IntuitionBase)
  431.         CurrentTime( &fileSecs, &fileMicro );
  432. #endif /* AMIGA */
  433.     return('D');                                /* Switch to data state */
  434. }
  435.  
  436.  
  437. /*
  438.  *  rinit
  439.  *        receive init
  440.  */
  441. rinit()
  442. {
  443.     if ((*openpk)())
  444.         return(0);
  445.     return('F');
  446. }
  447.